﻿module Sustainalytics.Insights.Admin {

    import Common = Sustainalytics.Common;
    import CommonAdmin = Sustainalytics.Common.Admin;
    import Pager = Sustainalytics.Pager;

    export class InsightsListController {

        // specifies whether current controller is in loading state
        public isLoading: boolean;
        public isLoadingList: boolean;

        // controller scope
        public $scope: ng.IScope;

        // services
        private $q: ng.IQService;
        private $location: ng.ILocationService;
        private notificationFactory: Common.INotificationFactory;
        private backendService: InsightsBackendService; 

        // nomeclators list
        public topicNames: InsightTopicName[];
        public sectorNames: InsightSectorName[];              

        // serach options
        public filter: InsightFilterDto;  

        // paged list of news
        public insightsPaged: Common.PagedList<InsightDtoUi>;

        // select all flag
        public selectAll: boolean; 
        
        // text for display in status
        public statusText: string[];

        constructor(
            $scope: ng.IScope,
            $q: ng.IQService,
            $location: ng.ILocationService,
            backend: InsightsBackendService,
            notificationFactory: Common.INotificationFactory) {
            
            var ctx = this;

            ctx.$scope = $scope;
            ctx.$q = $q;
            ctx.backendService = backend;
            ctx.notificationFactory = notificationFactory;
            ctx.$location = $location;

            //ctx.itemCount = 0;
            ctx.selectAll = false;

            // texts 
            ctx.statusText = [];
            ctx.statusText[0] = "Draft";
            ctx.statusText[1] = "Published";// diferent from DB 
            ctx.statusText[2] = "Unpublished";
            ctx.statusText[3] = "Unpublished";

            // pager
            ctx.insightsPaged = new Common.PagedList<InsightDtoUi>();

            
           
            ctx.prepareCurrentPageSize();

            // filter 
            ctx.filter = new InsightFilterDto();

            // load all required data
            ctx.load();
     
            $scope['insightList'] = ctx;

            //set up watches 
            ctx.setWatches();

            // notify parents that the controller was created
            $scope.$emit('insightList.created', ctx);
        }
        
        public addInsight() {
            this.$location.path('/insights/add');
        }
        public editInsight(id: string) {
            this.$location.path('/insights/edit/' + id);
        }

        public getSelectedItems(): InsightDtoUi[]{
            var ctx = this;
            if (ctx.insightsPaged && ctx.insightsPaged.items && ctx.insightsPaged.items.length > 0) {
                var items = $(ctx.insightsPaged.items).filter(function () { return this.selected; }).get();
                return items;
            }
            return new Array();
        }


        public short50Chars(input: string): string {

            if (input.length > 50)
                return input.substr(0, 46) + " ...";

            return input;
        }
        private setWatches() {

            var ctx = this;
            //on select all
            ctx.$scope.$watch('insightList.selectAll', () => {
                if (ctx.insightsPaged && ctx.insightsPaged.items && ctx.insightsPaged.items.length > 0)
                    $(ctx.insightsPaged.items).each(function () { this.selected = ctx.selectAll; });
            });

            //pager changed 
            ctx.$scope.$on('pagerChanged', (event, pager: Common.PagedList<InsightDtoUi>) => {

                ctx.backendService.putSetting("pageSize", pager.pagingOptions.pageSize);
                ctx.loadInsights(pager.pagingOptions.pageIndex);
            });


            //on filter change
            ctx.$scope.$watch('insightList.filter.insightTopicId', () => { ctx.loadInsights(1); });
            ctx.$scope.$watch('insightList.filter.insightSectorId', () => { ctx.loadInsights(1); });
            ctx.$scope.$watch('insightList.filter.titlePart', () => {

               // if ( ctx.filter.titlePart == "" || ctx.filter.titlePart.length >= 3)
                    ctx.loadInsights(1);
            });
        }
        private load(): ng.IPromise<{}> {
            var ctx = this;

            ctx.isLoading = true;
            var nomenclatorsPromise = ctx.loadNomenclators();
            var insightsListPromise = ctx.loadInsights(1);

            var allPromise = ctx.$q.all([nomenclatorsPromise, insightsListPromise]);

            allPromise.finally(() => { ctx.isLoading = false; });
            return allPromise;
        }
        private loadNomenclators(): ng.IPromise<InsightHelperDto> {

            var ctx = this;
            var getPromise: ng.IPromise<InsightHelperDto> = ctx.backendService.getNomenclators();
            getPromise.then((helper: InsightHelperDto) => {

                if (helper) {
                    ctx.topicNames = helper.topicNames;
                    ctx.sectorNames = helper.sectorNames.sort((a, b) => {
                        if (a.name > b.name)
                            return 1;
                        if (a.name < b.name)
                            return -1;

                        return 0;
                    });
                }
            });
            return getPromise;
        }
        private loadInsights(pageIndex?: number): ng.IPromise<Common.PagedList<InsightDtoUi[]>> {

            var ctx = this;
            ctx.isLoadingList = true;
            
            var pager: Pager.PagerController = ctx.$scope['pager'];
            if (!pager)
                return;

            if (pageIndex != null)
                pager.pagingOptions.pageIndex = pageIndex;


            var ps = parseInt(ctx.backendService.getSetting("pageSize"));
            if (isNaN(ps))
                ps = pager.pagingOptions.pageSize;
            else
                pager.pagingOptions.pageSize = ps;

            var gridOptions = new CommonAdmin.HttpGetOptionsDto();
            gridOptions.skip = (pager.pagingOptions.pageIndex - 1) * pager.pagingOptions.pageSize;
            console.log("pager.pagingOptions.pageIndex " + pager.pagingOptions.pageIndex + " gridOptions.skip  " + gridOptions.skip);
            gridOptions.take = pager.pagingOptions.pageSize;
            gridOptions.orderBy = ["DatePublished"];
            gridOptions.orderAscending = false;


            var getElemsCountPromise: ng.IPromise<number> = ctx.backendService.insightGetCount(ctx.filter);
            var getElemsPromise: ng.IPromise<InsightDtoUi[]> = ctx.backendService.insightGetList(ctx.filter, gridOptions);

            var twoPromise = ctx.$q.all([getElemsCountPromise, getElemsPromise]);

            getElemsCountPromise.then((count: number) => { ctx.insightsPaged.totalItemsCount = count; });
            getElemsPromise.then((list: InsightDtoUi[]) => { ctx.insightsPaged.items = list; });


            twoPromise.then(() => {
                
                var pager2: Pager.PagerController = ctx.$scope['pager'];
                if (!pager2)
                    return;

                var currentPage = pager2.pagingOptions.pageIndex;

                pager2.loadPagingFromPagedList(ctx.insightsPaged);
                
               //  if current page is empty but there are items then go to previous page
                if (ctx.insightsPaged.totalItemsCount > 0 && ctx.insightsPaged.items.length == 0 && ctx.insightsPaged.pagingOptions.pageIndex > 1) {
                    var prevPage = Math.min(ctx.insightsPaged.totalPageCount, currentPage - 1);

                    if (prevPage > 0) 
                        ctx.loadInsights(prevPage);
                }
            });
            
            twoPromise.finally(() => { ctx.isLoadingList = false; });
            return;
        }

        private prepareCurrentPageSize() {

            var ctx = this;
            var ps = parseInt(ctx.backendService.getSetting("pageSize"));
            if (isNaN(ps))
                ps = 20;
         
            ctx.insightsPaged.pagingOptions = new Common.PagingOptions(1, ps);
            
        }

        public deleteInsights() : ng.IPromise<Object> {

            var ctx = this;
            var def = ctx.$q.defer();
            var items = ctx.getSelectedItems();

            // check we have something to delete 
            if (items.length == 0) {
                //‘Please make a selection and try again’          
                ctx.notificationFactory.error('', "Please make a selection and try again");
                def.resolve();
                return def.promise;
            }

            // check all are drafts
            // count drafts
            var drafts = 0;
            items.forEach((item: InsightDtoUi) => {
                if (item.state == 0)
                    drafts++;
            });
            //if (items.length != drafts) {
            //    ctx.notificationFactory.error('', "Only items in status Draft can be deleted, please check your selection and try again");
            //    def.resolve();
            //    return def.promise;
            //}

          
            //all are draft, get confirmation 
            if (confirm('Are you sure you want to delete this(these) item(s)?') == false) {
                def.resolve();
                return def.promise;
            } 


            // ok to delete 
            ctx.isLoading = true;

            var promise: ng.IPromise<boolean> = ctx.backendService.insightDelete(items);
            promise
                .then(
                        () => ctx.notificationFactory.success('The items were deleted.'),
                        () => ctx.notificationFactory.error('', 'Failed to delete the items!'))
                .finally(() => {
                    
                    ctx.isLoading = false;
                    ctx.loadInsights();
                }); 
            
            def.resolve(promise);
            return def.promise;
        }
        public publishInsights(): ng.IPromise<Object> {

            var ctx = this;
            var def = ctx.$q.defer();
            var items = ctx.getSelectedItems();

            // check we have something to delete 
            if (items.length == 0) {
                //‘Please make a selection and try again’          
                ctx.notificationFactory.error('', "Please make a selection and try again");
                def.resolve();
                return def.promise;
            }

            // check all are drafts
            // count drafts
            var drafts = 0;
            items.forEach((item: InsightDtoUi) => {
                if (item.state == 0)
                    drafts++;
            });
            if (items.length != drafts) {
                ctx.notificationFactory.error('', "Only items in status Draft can be published, please check your selection and try again");
                def.resolve();
                return def.promise;
            }


            //all are draft, get confirmation 
            if (confirm(drafts.toString() +  ' items will be  published') == false) {
                def.resolve();
                return def.promise;
            }


            // ok to publish 
            ctx.isLoading = true;

            var promise: ng.IPromise<boolean> = ctx.backendService.insightUpdate(items, 1);
            promise
                .then(
                () => ctx.notificationFactory.success('The items were published.'),
                () => ctx.notificationFactory.error('', 'Failed to published the items!'))
                .finally(() => {

                    ctx.isLoading = false;
                    ctx.loadInsights();
                });

            def.resolve(promise);
            return def.promise;
        }
    }


    // register controller with News Angular module
    var mod = angular.module(insightsAdminModuleName);

    mod.controller('InsightsListController',
        ['$scope', '$q', '$location', 'InsightsBackendService', 'notificationFactory', InsightsListController]);
}